from casevo import AgentBase, TotLog
import random
import json
import os

class SimpleAgent(AgentBase):
    """简化版ABM代理"""
    
    def __init__(self, unique_id, model, profile=None):
        """
        初始化代理
        
        Args:
            unique_id: 代理的唯一ID
            model: 模型实例
            profile: 代理配置文件
        """
        # 设置代理描述和上下文
        description = {
            "confidence": profile.get('confidence', 0.5) if profile else 0.5,
            "self_censorship": profile.get('self_censorship', 0.5) if profile else 0.5
        }
        context = {
            "interaction_threshold": model.config.get('agent', {}).get('interaction_threshold', 0.3)
        }
        
        # 初始化父类
        super().__init__(unique_id, model, description, context)
        
        # 设置代理属性
        self.profile = profile or {}
        self.name = self.profile.get('name', f'Agent_{unique_id}')
        self.age = self.profile.get('age', 30)
        self.learned = self.profile.get('learned', '普通用户')
        self.care = self.profile.get('care', '')
        self.opinion = self._parse_opinion(self.profile.get('initial_opinion', 0))
        self.confidence = description['confidence']
        self.self_censorship = description['self_censorship']
        
        # 初始化历史记录
        self.opinion_history = [self.opinion]
        self.confidence_history = [self.confidence]
        
    def _parse_opinion(self, opinion_value):
        """
        解析意见值
        
        Args:
            opinion_value: 意见值，可以是数值或文本
            
        Returns:
            float: 解析后的意见值，范围[-1,1]
        """
        if isinstance(opinion_value, (int, float)):
            # 如果已经是数值，直接返回（并确保在[-1,1]区间）
            return max(-1.0, min(1.0, float(opinion_value)))
            
        if not opinion_value:
            return random.uniform(-1.0, 1.0)
            
        # 文本分析（保留原有逻辑）
        positive_words = ['支持', '赞成', '好', '应该', '需要', '重要']
        negative_words = ['反对', '不赞成', '不好', '不应该', '不需要', '不重要']
        score = 0
        for word in positive_words:
            if word in opinion_value:
                score += 1
        for word in negative_words:
            if word in opinion_value:
                score -= 1
        return max(-1.0, min(1.0, score / 3.0))
        
    def step(self):
        """代理步进"""
        # 获取邻居
        neighbors = self.model.grid.get_neighbors(self.pos, moore=True, include_center=False)
        if not neighbors:
            return
            
        # 随机选择一个邻居
        neighbor = random.choice(neighbors)
        
        # 计算意见差异
        opinion_diff = abs(self.opinion - neighbor.opinion)
        
        # 计算互动概率
        interaction_prob = 1.0 - opinion_diff
        
        # 考虑自我审查
        interaction_prob *= (1.0 - self.self_censorship)
        
        # 决定是否互动
        if random.random() < interaction_prob:
            # 计算意见更新
            self_confidence = self.confidence
            neighbor_confidence = neighbor.confidence
            
            # 计算权重
            total_confidence = self_confidence + neighbor_confidence
            if total_confidence > 0:
                self_weight = self_confidence / total_confidence
                neighbor_weight = neighbor_confidence / total_confidence
                
                # 更新意见
                new_opinion = (self.opinion * self_weight + 
                             neighbor.opinion * neighbor_weight)
                
                # 更新自信度
                new_confidence = (self.confidence + neighbor.confidence) / 2
                
                # 应用更新
                self.opinion = new_opinion
                self.confidence = new_confidence
                
                # 记录历史
                self.opinion_history.append(self.opinion)
                self.confidence_history.append(self.confidence)
                
                # 记录日志
                TotLog.add_agent_log(
                    tar_ts=self.model.step_count,
                    tar_type="interaction",
                    tar_item={
                        "agent_id": self.unique_id,
                        "neighbor_id": neighbor.unique_id,
                        "old_opinion": self.opinion,
                        "new_opinion": self.opinion,
                        "old_confidence": self.confidence,
                        "new_confidence": self.confidence
                    },
                    tar_agent_id=self.unique_id
                )
                
    def get_state(self):
        """获取代理状态"""
        return {
            "id": self.unique_id,
            "name": self.name,
            "age": self.age,
            "learned": self.learned,
            "care": self.care,
            "opinion": self.opinion,
            "confidence": self.confidence,
            "self_censorship": self.self_censorship,
            "opinion_history": self.opinion_history,
            "confidence_history": self.confidence_history
        } 